package com.jzcn.admin.shiro;


import com.jzcn.common.exceptions.BusinessException;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.servlet.HandlerExceptionResolver;

import java.util.LinkedHashMap;
import java.util.Map;


@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl("/api/public/unLogin");
        shiroFilter.setUnauthorizedUrl("/api/public/noPermissions");
        Map<String, String> filterMap = new LinkedHashMap<>();
        //资源文件
        filterMap.put("/favicon.ico**", "anon");
        filterMap.put("/js/**", "anon");
        filterMap.put("/docs/**", "anon");
        filterMap.put("/fonts/**", "anon");
        filterMap.put("/swagger-ui/**", "anon");
        filterMap.put("/doc.html", "anon");
        filterMap.put("/swagger-resources/**", "anon");
        filterMap.put("/v3/**", "anon");
        filterMap.put("/webjars/**", "anon");

        //登录 退出可以正常访问，不需要携带凭证
        filterMap.put("/api/public/login", "anon");
        filterMap.put("/api/enterprise/**", "anon");
        /*filterMap.put("/core/post/create", "roles[admin]");
        filterMap.put("/core/post/page2", "perms[post:page]");*/
        //对所有用户认证
        filterMap.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

    /**
     * 安全管理器
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(customRelam());
        return securityManager;
    }


    @Bean
    public CustomRelam customRelam() {
        CustomRelam customRelam = new CustomRelam();
        // 设置是否需求缓存权限
        customRelam.setAuthorizationCachingEnabled(true);
        return customRelam;
    }


    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @return
     */
    @Bean
    //@DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    /**
     * 开启shiro aop注解支持.
     * 使用代理方式;所以需要开启代码支持;
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * Shiro生命周期处理器
     */
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public Cookie sessionIdCookie() {
        Cookie cookie = new SimpleCookie();
        cookie.setName("USERSESSIONID");
        cookie.setMaxAge(3000);
        cookie.setSecure(false);
        cookie.setHttpOnly(false);
        return cookie;
    }

}
